home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2002 November / SGI Freeware 2002 November - Disc 2.iso / dist / fw_glimpse.idb / usr / freeware / src / glimpse-3.0 / communicate.c.z / communicate.c
C/C++ Source or Header  |  1997-09-09  |  9KB  |  437 lines

  1. /* rewritten so that it uses no library routines */
  2. #if    SFS_COMPAT
  3. #if defined(__NeXT__)
  4. #include <syscall.h>
  5. #else
  6. #include <sys/syscall.h>
  7. #endif
  8. #endif
  9. #include <stdlib.h>
  10. #include <sys/types.h>
  11. #include <sys/socket.h>
  12. #include <sys/un.h>
  13. #include <netinet/in.h>
  14. #include <arpa/inet.h>
  15. #include <netdb.h>
  16. /* #include <sys/uio.h> */
  17. /* #include <sgtty.h> */
  18. #include <signal.h>
  19. #if    1
  20. #if defined(_IBMR2)
  21. #include <sys/select.h>
  22. #endif
  23. #else
  24. #if defined(HAVE_SYS_SELECT_H)
  25. #include <sys/select.h>
  26. #endif
  27. #endif
  28.  
  29. #include "glimpse.h"
  30. #include "defs.h"
  31.  
  32. int
  33. mystrlen(str, max)
  34.     char    *str;
  35.     int    max;
  36. {
  37.     int    i=0;
  38.  
  39.     while ((i<max) && (str[i] != '\0')) i++;
  40.     return i;
  41. }
  42.  
  43. int
  44. readn(fd, ptr, nbytes)
  45. int    fd;
  46. char    *ptr;
  47. int    nbytes;
  48. {
  49.     int    nleft, nread;
  50.  
  51.     nleft = nbytes;
  52.     while (nleft > 0) {
  53. #if    SFS_COMPAT
  54.         nread = syscall(SYS_read, fd, ptr, nleft);
  55. #else
  56.         nread = read(fd, ptr, nleft);
  57. #endif
  58.         if (nread < 0) return(nread);
  59.         else if (nread == 0) break;    /* EOF */
  60.         nleft -= nread;
  61.         ptr += nread;
  62.     }
  63.     return (nbytes - nleft);
  64. }
  65.  
  66. int
  67. writen(fd, ptr, nbytes)
  68. int    fd;
  69. char    *ptr;
  70. int    nbytes;
  71. {
  72.     int    nleft, nwritten;
  73.  
  74.     nleft = nbytes;
  75.     while (nleft > 0) {
  76. #if    SFS_COMPAT
  77.         nwritten = syscall(SYS_write, fd, ptr, nleft);
  78. #else
  79.         nwritten = write(fd, ptr, nleft);
  80. #endif
  81.         if (nwritten <= 0) return nwritten;
  82.         nleft -= nwritten;
  83.         ptr += nwritten;
  84.     }
  85.     return (nbytes - nleft);
  86. }
  87.  
  88. int
  89. readline(sockfd, ptr, maxlen)
  90. int    sockfd;
  91. char    *ptr;
  92. int    maxlen;
  93. {
  94.     int    n, rc;
  95.     char    c;
  96.  
  97.     for (n=1; n<maxlen; n++) {
  98.         if ((rc = readn(sockfd, &c, 1)) == 1) {
  99.             *ptr++ = c;
  100.             if (c == '\n') break;
  101.         } else if (rc == 0) {
  102.             if (n==1) return (0);    /* EOF */
  103.             else break;
  104.         } else return (-1);
  105.     }
  106.     *ptr = 0;
  107.     return n;
  108. }
  109.  
  110. #if    USE_MSGHDR
  111. /*
  112.  * This piece of code was causing compilation problems.
  113.  * It was not being used anyway. So it has been deleted.
  114.  * -bg, Jan 4th 95
  115.  */
  116.  
  117. int
  118. sendfile(sockfd, fds, num)
  119. int    sockfd, fds[], num;
  120. {
  121.     struct iovec    iov[1];
  122.     struct msghdr    msg;
  123.     int        ret;
  124.  
  125.     iov[0].iov_base = (char *) NULL;
  126.     iov[0].iov_len = 0;
  127.     msg.msg_iov = iov;
  128.     msg.msg_iovlen = 1;
  129.     msg.msg_name = (caddr_t) NULL;
  130.     msg.msg_namelen = 0;
  131.     msg.msg_accrights = (caddr_t) fds;
  132.     msg.msg_accrightslen = num * sizeof(int);
  133.  
  134.     errno = 0;
  135. #if    SFS_COMPAT
  136.     if ((ret = syscall(SYS_sendmsg, sockfd, &msg, 0)) < 0) {
  137. #else
  138.     if ((ret = sendmsg(sockfd, &msg, 0)) < 0) {
  139. #endif
  140. #if    0
  141.     printf("sendmsg ret = %x, errno = %d\n", ret, errno);
  142. #endif
  143.         return (-1);
  144.     }
  145. #if    0
  146.     printf("sent fds %x %x %x, ret = %x, errno = %d\n", fds[0], fds[1], fds[2], ret, errno);
  147. #endif
  148.     return (0);
  149. }
  150.  
  151. int
  152. send_clfds(sockfd, clstdin, clstdout, clstderr)
  153. int    sockfd, clstdin, clstdout, clstderr;
  154. {
  155.     int    fds[3];
  156.  
  157.     fds[0] = clstdin;
  158.     fds[1] = clstdout;
  159.     fds[2] = clstderr;
  160.     if (sendfile(sockfd, fds, 3) < 0) return -1;
  161.     return 0;
  162. }
  163.  
  164. int
  165. getfile(sockfd, fds, num)
  166. int    sockfd, fds[], num;
  167. {
  168.     struct iovec    iov[1];
  169.     struct msghdr    msg;
  170.     int        ret;
  171.  
  172.     iov[0].iov_base = (char *) NULL;
  173.     iov[0].iov_len = 0;
  174.     msg.msg_iov = iov;
  175.     msg.msg_iovlen = 1;
  176.     msg.msg_name = (caddr_t) NULL;
  177.     msg.msg_namelen = 0;
  178.     msg.msg_accrights = (caddr_t)fds;
  179.     msg.msg_accrightslen = num*sizeof(int);
  180.  
  181.     errno = 0;
  182. #if    SFS_COMPAT
  183.     if ((ret = syscall(SYS_recvmsg, sockfd, &msg, 0)) < 0) {
  184. #else
  185.     if ((ret = recvmsg(sockfd, &msg, 0)) < 0) {
  186. #endif
  187. #if    0
  188.         printf("bad recvmsg: ret = %x, errno = %d\n", ret, errno);
  189. #endif
  190.         return -1;
  191.     }
  192. #if    0
  193.     printf("got fds %x %x %x, ret = %x, errno = %d\n", fds[0], fds[1], fds[2], ret, errno);
  194. #endif
  195.     return 0;
  196. }
  197.  
  198. int
  199. get_clfds(sockfd, pclstdin, pclstdout, pclstderr)
  200. int    sockfd, *pclstdin, *pclstdout, *pclstderr;
  201. {
  202.     int    fds[3];
  203.  
  204.     if (getfile(sockfd, fds, 3) < 0) return -1;
  205.     if (((*pclstdin = fds[0]) < 0) || (*pclstdin >= 20)) return -1;
  206.     if (((*pclstdout = fds[1]) < 0) || (*pclstdout >= 20)) return -1;
  207.     if (((*pclstderr = fds[2]) < 0) || (*pclstderr >= 20)) return -1;
  208.     return 0;
  209. }
  210. #endif    /*USE_MSGHDR*/
  211.  
  212. int
  213. linearize(sockfd, reqbuf, reqlen, argc, argv, pid)
  214. int    sockfd;
  215. int    reqlen, argc;
  216. char    *reqbuf, *argv[];
  217. int    pid;
  218. {
  219.     int    i;
  220.     unsigned char    array[4];
  221.     int    ptr = 0;
  222.     int    len;
  223.  
  224.     array[0] = (pid & 0xff000000) >> 24;
  225.     array[1] = (pid & 0xff0000) >> 16;
  226.     array[2] = (pid & 0xff00) >> 8;
  227.     array[3] = (pid & 0xff);
  228.     if (sockfd >= 0) {
  229.         if (writen(sockfd, array, 4) < 4) return -1;
  230.     }
  231.     if (reqbuf != NULL) {
  232.         if (ptr + 4 >= reqlen) return -1;
  233.         memcpy(reqbuf+ptr, array, 4);
  234.         ptr += 4;
  235.     }
  236.  
  237.     array[0] = (argc & 0xff000000) >> 24;
  238.     array[1] = (argc & 0xff0000) >> 16;
  239.     array[2] = (argc & 0xff00) >> 8;
  240.     array[3] = (argc & 0xff);
  241.     if (sockfd >= 0) {
  242.         if (writen(sockfd, array, 4) < 4) return -1;
  243.     }
  244.     if (reqbuf != NULL) {
  245.         if (ptr + 4 >= reqlen) return -1;
  246.         memcpy(reqbuf+ptr, array, 4);
  247.         ptr += 4;
  248.     }
  249.  
  250.     for (i=0; i<argc; i++) {
  251.         len = strlen(argv[i]);
  252.         if (sockfd >= 0) {
  253.             if (writen(sockfd, argv[i], len + 1) < len + 1) return -1;
  254.             if (writen(sockfd, "\n", 1) < 1) return -1;    /* so that we can do gets */
  255.         }
  256.         if (reqbuf != NULL) {
  257.             if (ptr + len + 2 >= reqlen) return -1;
  258.             strcpy(reqbuf+ptr, argv[i]);
  259.             ptr += len+1;
  260.             reqbuf[ptr++] = '\0';    /* so that we can do strcpy */
  261.         }
  262. #if    0
  263.         printf("sending %s\n", argv[i]);
  264. #endif
  265.     }
  266.     return ptr;
  267. }
  268.  
  269. int
  270. delinearize(sockfd, reqbuf, reqlen, pargc, pargv, ppid)
  271. int    sockfd;
  272. int    reqlen, *pargc;
  273. char    *reqbuf, **pargv[];
  274. int    *ppid;
  275. {
  276.     int    i;
  277.     char    line[MAXLINE];
  278.     int    len;
  279.     int    ptr = 0;
  280.     unsigned char    array[4];
  281.  
  282.     *ppid = 0;
  283.     *pargc = 0;
  284.     *pargv = NULL;
  285.     memset(array, '\0', 4);
  286.  
  287.     if (sockfd >= 0) if (readn(sockfd, array, 4) != 4) return -1;
  288.     if (reqbuf != NULL) {
  289.         if (ptr+4 >= reqlen) return -1;
  290.         memcpy(array, reqbuf+ptr, 4);
  291.         ptr += 4;
  292.     }
  293.     *ppid = (array[0] << 24) + (array[1] << 16) + (array[2] << 8) + array[3];
  294.  
  295.     memset(array, '\0', 4);
  296.     if (sockfd >= 0) if (readn(sockfd, array, 4) != 4) return -1;
  297.     if (reqbuf != NULL) {
  298.         if (ptr+4 >= reqlen) return -1;
  299.         memcpy(array, reqbuf+ptr, 4);
  300.         ptr += 4;
  301.     }
  302.     *pargc = (array[0] << 24) + (array[1] << 16) + (array[2] << 8) + array[3];
  303. #if    0
  304.     printf("clargc=%x\n", *pargc);
  305. #endif
  306.     /* VERY important, set hard-coded limit to MAX_ARGS*MAX_NAME_LEN; otherwise can cause the server to allocate TONS of memory */
  307.     if (*pargc <= 0 || *pargc >= (MAX_ARGS*MAX_NAME_LEN)) { *pargc = 0; return -1; }
  308.  
  309.     if ((*pargv = (char **)malloc(sizeof(char *) * *pargc)) == NULL) {
  310.         /* no memory, so discard */
  311.         *pargc = 0;
  312.         return - 1;
  313.     }
  314.     memset(*pargv, '\0', sizeof(char *) * *pargc);
  315.     for (i=0; i<*pargc; i++) {
  316.         if (sockfd >= 0) {
  317.             if (readline(sockfd, line, MAXLINE) <= 0) return -1;
  318.             if ((len = mystrlen(line, MAXLINE)) <= 0) {
  319.                 i--;
  320.                 continue;
  321.             }
  322.             if (((*pargv)[i] = (char *)malloc(len + 2)) == NULL) return -1;
  323.             line[len] = '\0';    /* overwrite the '\n' */
  324.             strcpy((*pargv)[i], line);
  325.         }
  326.         if (reqbuf != NULL) {
  327.             if ( ((len = mystrlen(reqbuf+ptr, reqlen-ptr)) <= 0) || (len >= MAXLINE) ) return -1;
  328.             if (((*pargv)[i] = (char *)malloc(len + 2)) == NULL) return -1;
  329.             strcpy((*pargv)[i], reqbuf+ptr);
  330.             ptr += len + 2;
  331.         }
  332. #if    0
  333.         printf("clargv[%x]=%s\n", i, (*pargv)[i]);
  334. #endif
  335.     }
  336.     return ptr;
  337. }
  338.  
  339. int
  340. sendreq(sockfd, reqbuf, clstdin, clstdout, clstderr, clargc, clargv, clpid)
  341. int    sockfd, clstdin, clstdout, clstderr, clargc, clpid;
  342. char    reqbuf[MAX_ARGS*MAX_NAME_LEN], *clargv[];
  343. {
  344. #if    USE_MSGHDR
  345.     struct iovec    iov[1];
  346.     struct msghdr    msg;
  347.     int        ret;
  348.     int        fds[3];
  349. #endif    /*USE_MSGHDR*/
  350.  
  351. #if    USE_MSGHDR
  352.     if ((ret = linearize(-1, reqbuf, MAX_ARGS*MAX_NAME_LEN, clargc, clargv, clpid)) < 0) return -1;
  353.  
  354.     fds[2] = clstdin;
  355.     fds[1] = clstdout;
  356.     fds[0] = clstderr;
  357.  
  358.     iov[0].iov_base = (char *) reqbuf;
  359.     iov[0].iov_len = ret;
  360.     msg.msg_iov = iov;
  361.     msg.msg_iovlen = 1;
  362.     msg.msg_name = (caddr_t) NULL;
  363.     msg.msg_namelen = 0;
  364.     msg.msg_accrights = (caddr_t) fds;
  365.     msg.msg_accrightslen = 2 * sizeof(int);    /* don't send clstdin */
  366.  
  367.     errno = 0;
  368. #if    SFS_COMPAT
  369.     if ((ret = syscall(SYS_sendmsg, sockfd, &msg, 0)) < 0) {
  370. #else
  371.     if ((ret = sendmsg(sockfd, &msg, 0)) < 0) {
  372. #endif
  373. #if    0
  374.     printf("sendmsg ret = %x, errno = %d\n", ret, errno);
  375. #endif
  376.         return (-1);
  377.     }
  378. #if    0
  379.     printf("sendreq %x %x %x, ret = %x, errno = %d\n", fds[0], fds[1], fds[2], ret, errno);
  380. #endif
  381. #else    /*USE_MSGHDR*/
  382.     if (linearize(sockfd, (char *)NULL, MAX_ARGS*MAX_NAME_LEN, clargc, clargv, clpid) < 0) return -1;
  383. #endif    /*USE_MSGHDR*/
  384.     return (0);
  385. }
  386.  
  387. int
  388. getreq(sockfd, reqbuf, pclstdin, pclstdout, pclstderr, pclargc, pclargv, pclpid)
  389. int    sockfd, *pclstdin, *pclstdout, *pclstderr, *pclargc, *pclpid;
  390. char    reqbuf[MAX_ARGS*MAX_NAME_LEN], **pclargv[];
  391. {
  392. #if    USE_MSGHDR
  393.     struct iovec    iov[1];
  394.     struct msghdr    msg;
  395.     int        ret;
  396.     int        fds[3];
  397. #endif    /*USE_MSGHDR*/
  398.  
  399. #if    USE_MSGHDR
  400.     iov[0].iov_base = (char *) reqbuf;
  401.     iov[0].iov_len = MAX_ARGS * MAX_NAME_LEN;
  402.     msg.msg_iov = iov;
  403.     msg.msg_iovlen = 1;
  404.     msg.msg_name = (caddr_t) NULL;
  405.     msg.msg_namelen = 0;
  406.     msg.msg_accrights = (caddr_t)fds;
  407.     msg.msg_accrightslen = 2*sizeof(int);
  408.  
  409.     errno = 0;
  410. #if    SFS_COMPAT
  411.     if ((ret = syscall(SYS_recvmsg, sockfd, &msg, 0)) < 0) {
  412. #else
  413.     if ((ret = recvmsg(sockfd, &msg, 0)) < 0) {
  414. #endif
  415. #if    0
  416.         printf("bad recvmsg: ret = %x, errno = %d\n", ret, errno);
  417. #endif
  418.         return -1;
  419.     }
  420.  
  421.     *pclstdin = fds[2];
  422.     *pclstdout = fds[1];
  423.     *pclstderr = fds[0];
  424.  
  425.     if ((ret == delinearize(-1, reqbuf, MAX_ARGS * MAX_NAME_LEN, pclargc, pclargv, pclpid)) < 0) return -1;
  426. #if    0
  427.     printf("getreq %x %x %x, ret = %x, errno = %d\n", fds[0], fds[1], fds[2], ret, errno);
  428. #endif
  429. #else    /*USE_MSGHDR*/
  430.     if (delinearize(sockfd, (char *)NULL, MAX_ARGS * MAX_NAME_LEN, pclargc, pclargv, pclpid) < 0) return -1;
  431.     *pclstdin = -1;
  432.     *pclstdout = sockfd;
  433.     *pclstderr = sockfd;
  434. #endif    /*USE_MSGHDR*/
  435.     return (0);
  436. }
  437.